/*
 * CcStatement.c
 *
 *  Created on: 2012/04/28
 *      Author: guanxiaoying
 */
#include "../coredef.h"
#include "../table/table.h"
#include "cc.h"

static AST gblFunctionSym = 0;

static AST ccStmtBlock( U2 kind, AST parent );
static AST  ccStmtAnalyze( AST astParent );
static VOID ccStmtPushLoopOrSwitch( AST  astStmt );
static VOID ccStmtPullLoopOrSwitch( VOID );
static CHAR gblTempBuffer[128]="";
static VOID ccStmtCheckExpType( U2 usStmtKind, AST astCondExpr ){
	AST astTypeIndex;	/*型情報連番*/

	if( stExpressionAccess.bIllegal.get( astCondExpr ) ){
		return;
	}
	astTypeIndex = stExpressionAccess.castedType.get( astCondExpr );
	switch (usStmtKind ){
		case xSTMT_DO:
			if (!CcTypeIsScalar(astTypeIndex)){
				CcThrowWarning( CC_STMT_CONDEXP_NEED_SCALAR,
						stExpressionAccess.codeScp.get( astCondExpr ),
						"do", NULL );
			}
			break;
		case xSTMT_WHILE:
			if (!CcTypeIsScalar(astTypeIndex)){
				CcThrowWarning( CC_STMT_CONDEXP_NEED_SCALAR,
						stExpressionAccess.codeScp.get( astCondExpr ),
						"while", NULL );
			}
			break;
		case xSTMT_IF:
			if (!CcTypeIsScalar(astTypeIndex)){
				CcThrowWarning( CC_STMT_CONDEXP_NEED_SCALAR,
						stExpressionAccess.codeScp.get( astCondExpr ),
						"if", NULL );
			}
			break;
		case xSTMT_FOR:
			if (!CcTypeIsScalar(astTypeIndex)){
				CcThrowWarning( CC_STMT_CONDEXP_NEED_SCALAR,
						stExpressionAccess.codeScp.get( astCondExpr ),
						"for", NULL );
			}
			break;
		case  xSTMT_SWITCH:
			if (!CcTypeIsInteger(astTypeIndex)){
				CcThrowWarning( CC_STMT_CONDEXP_NEED_INTEGER,
						stExpressionAccess.codeScp.get( astCondExpr ),
						"switch", NULL );
			}
			break;
		default:
			break;
	}
}
static VOID ccStmtPushLoopOrSwitch( AST  astStmt ){
	AST astMax;
	stCCLoopSwitchStackAccess.alloc(1);
	astMax = stCCLoopSwitchStackAccess.getMax();
	stCCLoopSwitchStackAccess.statement.set( astMax, astStmt );
}
static VOID ccStmtPullLoopOrSwitch( VOID ){
	stCCLoopSwitchStackAccess.alloc(-1);
}
static  AST  ccStmtExpression( AST astParent ){
	AST  astExpStmt=0;
	AST  astExprInfo=0;
	U4   ulEndToken[2];
	AST  astCurrToken;
	U4    currTokenKind;
	AST  firstScp, secondScp;

	TRY;
	astCurrToken = CcLexGetCurrToken();
	firstScp = stLexTokenAccess.codeScp.get( astCurrToken );

	stStatementAccess.alloc(1);
	astExpStmt = stStatementAccess.getMax();
	stStatementAccess.parentKind.set( astExpStmt, KIND_STATEMENTINFO );
	stStatementAccess.parent_statement.set( astExpStmt, astParent );
	stStatementAccess.statmentKind.set( astExpStmt, xSTMT_EXP );

	ulEndToken[0] = xLEX_SEMICOLON;
	ulEndToken[1] = xLEX_UNDEFINED;
	astExprInfo = CcExpression( ulEndToken, KIND_STATEMENTINFO, astExpStmt  );
	astCurrToken = CcLexGetCurrToken();
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
	if( currTokenKind == xLEX_SEMICOLON ){
		CcLexGetNextToken();
	}else{
		CcThrowWarning( CC_STMT_SYNTAX_ERROR,
				stLexTokenAccess.codeScp.get( astCurrToken ),
				stLexTokenAccess.name.get( astCurrToken ), NULL );
	}
	stStatementAccess.exp_exp.set( astExpStmt, astExprInfo );

	secondScp = stLexTokenAccess.codeScp.get( CcLexGetLF(1) );
	secondScp = stCoreCodeScpAccess.mergeCodeScp( firstScp, secondScp );
	stStatementAccess.codeScp.set( astExpStmt, secondScp );
	CATCH( astExpStmt );
	return ( astExpStmt );
}
static AST ccStmtLabel( AST astParent ){
	AST   astLabelStmt=0;
	AST   astChild;
	AST   astSymbol;
	PSZ   pszSymName;
	AST   astCurrToken;
	U4    currTokenKind;
	AST  firstScp, secondScp;

	TRY;
	astCurrToken = CcLexGetCurrToken();
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
	if( currTokenKind == xLEX_SYMBOL ){
		firstScp = stLexTokenAccess.codeScp.get( astCurrToken );
		pszSymName = stLexTokenAccess.name.get( astCurrToken );
		astSymbol = CcBlockFindLabel( pszSymName, NULL );
		astLabelStmt = stSymbolInfoAccess.value.get( astSymbol );
		if( astLabelStmt == 0 ){
			astLabelStmt = CcBlockAddLabelStatement( pszSymName );
		}
		CcLexGetNextToken();
		CcLexGetNextToken();
		astChild = ccStmtAnalyze(astLabelStmt);
		if( astChild == 0 ){
			CcThrowWarning( CC_STMT_NEED_BODY,
					stLexTokenAccess.codeScp.get( astCurrToken ),
					"label", NULL );
		}

		secondScp = stLexTokenAccess.codeScp.get( CcLexGetLF(1) );
		secondScp = stCoreCodeScpAccess.mergeCodeScp( firstScp, secondScp );
		stStatementAccess.codeScp.set( astLabelStmt, secondScp );

		if( stStatementAccess.label_statement.get(astLabelStmt) > 0 ){
			CcThrowWarning( CC_STMT_LABEL_OVERLAP,
					stLexTokenAccess.codeScp.get( astCurrToken ),
					pszSymName, NULL );
			CcThrowWarning( CC_STMT_LABEL_OVERLAP1ST,
					stStatementAccess.codeScp.get( astLabelStmt ),
					pszSymName, NULL );
		}else{
			stStatementAccess.label_statement.set( astLabelStmt, astChild );
			astSymbol = stStatementAccess.label_name.get(astLabelStmt);
			stSymbolInfoAccess.codeScp.set( astSymbol, firstScp );
		}
		stStatementAccess.parentKind.set( astLabelStmt, KIND_STATEMENTINFO );
		stStatementAccess.parent_statement.set( astLabelStmt, astParent );
	}
	CATCH( astLabelStmt );
	return ( astLabelStmt );
}
static BOOL ccStmtIsLabelStmt( VOID ){
	AST   astCurrToken;
	U4    currTokenKind;

	astCurrToken = CcLexGetCurrToken();
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
	if( currTokenKind == xLEX_SYMBOL ){
		astCurrToken = CcLexGetRT(1);
		currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
		if( currTokenKind == xLEX_COLON ){
			return TRUE;
		}
	}
	return FALSE;
}
static AST ccStmtGoto( AST astParent ){
	AST   astGotoStmt=0;
	AST   astGotoChain;
	AST   astCurrChain;
	AST   astCurrToken;
	AST   astLabelStmt;
	AST   astSymbol;
	PSZ   pszSymName;
	U4    currTokenKind;
	AST  firstScp, secondScp;

	TRY;
	astCurrToken = CcLexGetCurrToken();
	firstScp = stLexTokenAccess.codeScp.get( astCurrToken );

	stStatementAccess.alloc(1);
	astGotoStmt = stStatementAccess.getMax();
	stStatementAccess.parentKind.set( astGotoStmt, KIND_STATEMENTINFO );
	stStatementAccess.parent_statement.set( astGotoStmt, astParent );
	stStatementAccess.statmentKind.set( astGotoStmt, xSTMT_GOTO );

	astCurrToken = CcLexGetNextToken();
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
	if( currTokenKind == xLEX_SYMBOL){
		pszSymName = stLexTokenAccess.name.get( astCurrToken );
		astSymbol  = CcBlockFindLabel( pszSymName, NULL );
		astLabelStmt = stSymbolInfoAccess.value.get( astSymbol );
		if( astLabelStmt == 0 ){
			astLabelStmt = CcBlockAddLabelStatement( pszSymName );
		}
		stStatementAccess.goto_sym.set( astGotoStmt, stStatementAccess.label_name.get(astLabelStmt) );
		stStatementAccess.goto_statement.set( astGotoStmt, astLabelStmt );

		stUniteChainAccess.alloc(1);
		astGotoChain = stUniteChainAccess.getMax();
		stUniteChainAccess.parameter_stmt.set( astGotoChain, astGotoStmt );
		astCurrChain = stStatementAccess.label_gotoChain.get( astLabelStmt );
		if( astCurrChain ){
			stStatementAccess.label_gotoChain.set( astLabelStmt, astGotoChain );
			stUniteChainAccess.next.set( astGotoChain, astCurrChain );
			stUniteChainAccess.before.set( astCurrChain, astGotoChain );
		}else{
			stStatementAccess.label_gotoChain.set( astLabelStmt, astGotoChain );
		}
	}else{
		CcThrowWarning( CC_STMT_SYNTAX_ERROR,
				stLexTokenAccess.codeScp.get( astCurrToken ),
				stLexTokenAccess.name.get( astCurrToken ), NULL );
	}
	astCurrToken = CcLexGetNextToken();
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
	if( currTokenKind != xLEX_SEMICOLON ){
		CcThrowWarning( CC_STMT_SYNTAX_ERROR,
				stLexTokenAccess.codeScp.get( astCurrToken ),
				stLexTokenAccess.name.get( astCurrToken ), NULL );
	}else{
		CcLexGetNextToken();
	}
	secondScp = stLexTokenAccess.codeScp.get( CcLexGetLF(1) );
	secondScp = stCoreCodeScpAccess.mergeCodeScp( firstScp, secondScp );
	stStatementAccess.codeScp.set( astGotoStmt, secondScp );
	CATCH(astGotoStmt);
	return( astGotoStmt );
}
static AST ccStmtReturn( AST astParent ){
	AST	astFunType ;		/*関数の型*/
	U4	ulEndToken[2]={xLEX_SEMICOLON,xLEX_UNDEFINED};	/*終了文字配列*/
	AST	astRetType ;		/*返却式の型*/
	AST astReturnStmt=0;
	AST astExprInfo=0;
	AST   astCurrToken;
	U4    currTokenKind;
	AST  firstScp, secondScp;

	TRY;
	astCurrToken = CcLexGetCurrToken();
	firstScp = stLexTokenAccess.codeScp.get( astCurrToken );

	stStatementAccess.alloc(1);
	astReturnStmt = stStatementAccess.getMax();
	stStatementAccess.parentKind.set( astReturnStmt, KIND_STATEMENTINFO );
	stStatementAccess.parent_statement.set( astReturnStmt, astParent );
	stStatementAccess.statmentKind.set( astReturnStmt, xSTMT_RETURN );

	astCurrToken = CcLexGetNextToken();
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
	if ( currTokenKind == xLEX_SEMICOLON){
		CcLexGetNextToken();
		astRetType = TYPE_VOID;
	}else{
		astExprInfo = CcExpression( ulEndToken, KIND_STATEMENTINFO, astReturnStmt  );
		astCurrToken = CcLexGetCurrToken();
		currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
		if( currTokenKind != xLEX_SEMICOLON ){
			CcThrowWarning( CC_STMT_SYNTAX_ERROR,
					stLexTokenAccess.codeScp.get( astCurrToken ),
					stLexTokenAccess.name.get( astCurrToken ), NULL );
		}else{
			astCurrToken = CcLexGetNextToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
		}
		stStatementAccess.return_exp.set( astReturnStmt, astExprInfo );
		if( astExprInfo == 0 ){
			astRetType = TYPE_VOID;
		}else{
			astRetType = stExpressionAccess.castedType.get( astExprInfo );
		}
	}
	astFunType = stSymbolInfoAccess.type.get( gblFunctionSym );
	astFunType = stTypeInfoAccess.elementType.get( astFunType );
	if( !CcTypeIsAssignable( astRetType, astFunType ) ){
		if( CcTypeIsPointer( astFunType ) && CcExprIsNullPointer( astExprInfo ) ){
			;
		}else{
			U2  errorflg = CcTypeCatchAssignableFlg();
			switch( errorflg ){
			case COMP_ASSIGN_DIFFQUALIFY_POINTER:
				break;
			case COMP_ASSIGN_UNCOMPATIBLE_POINTER:
			case COMP_ASSIGN_UNCOMPATIBLE:
			default:
				if( astExprInfo ){
					CcThrowWarning( CC_STMT_RETURN_VALUE_ILLEGAL,
							stExpressionAccess.codeScp.get( astExprInfo ),
						stLexTokenAccess.name.get( astCurrToken ), NULL );
				}else{
					CcThrowWarning( CC_STMT_RETURN_VALUE_ILLEGAL,
							firstScp,
						stLexTokenAccess.name.get( astCurrToken ), NULL );
				}
				break;
			}
		}
	}
	secondScp = stLexTokenAccess.codeScp.get( CcLexGetLF(1) );
	secondScp = stCoreCodeScpAccess.mergeCodeScp( firstScp, secondScp );
	stStatementAccess.codeScp.set( astReturnStmt, secondScp );
	CATCH(astReturnStmt);
	return ( astReturnStmt );
}
static AST ccStmtContinue( AST astParent ){
	AST astCtrlStmtNum ;
	AST astFatherStmt;
	U4 lCtrlKind ;
	AST astContinueStmt=0 ;

	AST   astCurrToken;
	U4    currTokenKind;
	AST  firstScp, secondScp;

	TRY;
	astCurrToken = CcLexGetCurrToken();
	firstScp = stLexTokenAccess.codeScp.get( astCurrToken );

	stStatementAccess.alloc(1);
	astContinueStmt = stStatementAccess.getMax();
	stStatementAccess.parentKind.set( astContinueStmt, KIND_STATEMENTINFO );
	stStatementAccess.parent_statement.set( astContinueStmt, astParent );
	stStatementAccess.statmentKind.set( astContinueStmt, xSTMT_CONTINUE );

	astCtrlStmtNum = stCCLoopSwitchStackAccess.getMax();
	while( astCtrlStmtNum >= MIN_ARRAY ){
		astFatherStmt = stCCLoopSwitchStackAccess.statement.get( astCtrlStmtNum );
		lCtrlKind = stStatementAccess.statmentKind.get( astFatherStmt );
		if(    lCtrlKind == xSTMT_DO
			|| lCtrlKind == xSTMT_WHILE
			|| lCtrlKind == xSTMT_FOR){
			break ;
		}
		astCtrlStmtNum-- ;
	}
	if( astCtrlStmtNum >= MIN_ARRAY ){
		stStatementAccess.continue_statement.set( astContinueStmt, astFatherStmt );
	}else{
		CcThrowWarning( CC_STMT_CONTINUE_OUTLOOP,
				firstScp,
			NULL, NULL );
	}
	astCurrToken = CcLexGetNextToken();
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
	if( currTokenKind != xLEX_SEMICOLON ){
		CcThrowWarning( CC_STMT_SYNTAX_ERROR,
				stLexTokenAccess.codeScp.get( astCurrToken ),
				stLexTokenAccess.name.get( astCurrToken ), NULL );
	}else{
		CcLexGetNextToken();
	}
	secondScp = stLexTokenAccess.codeScp.get( CcLexGetLF(1) );
	secondScp = stCoreCodeScpAccess.mergeCodeScp( firstScp, secondScp );
	stStatementAccess.codeScp.set( astContinueStmt, secondScp );
	CATCH(astContinueStmt);
	return( astContinueStmt ) ;
}
static AST ccStmtBreak( AST astParent ){
	AST astCtrlStmtNum ;
	AST astFatherStmt;
	U4 lCtrlKind ;
	AST astBreakStmt=0 ;

	AST   astCurrToken;
	U4    currTokenKind;
	AST  firstScp, secondScp;

	TRY;
	astCurrToken = CcLexGetCurrToken();
	firstScp = stLexTokenAccess.codeScp.get( astCurrToken );

	stStatementAccess.alloc(1);
	astBreakStmt = stStatementAccess.getMax();
	stStatementAccess.parentKind.set( astBreakStmt, KIND_STATEMENTINFO );
	stStatementAccess.parent_statement.set( astBreakStmt, astParent );
	stStatementAccess.statmentKind.set( astBreakStmt, xSTMT_BREAK );

	astCtrlStmtNum = stCCLoopSwitchStackAccess.getMax();
	while( astCtrlStmtNum >= MIN_ARRAY ){
		astFatherStmt = stCCLoopSwitchStackAccess.statement.get( astCtrlStmtNum );
		lCtrlKind = stStatementAccess.statmentKind.get( astFatherStmt );
		if(    lCtrlKind == xSTMT_DO
			|| lCtrlKind == xSTMT_WHILE
			|| lCtrlKind == xSTMT_FOR
			|| lCtrlKind == xSTMT_SWITCH ){
			break ;
		}
		astCtrlStmtNum-- ;
	}
	if( astCtrlStmtNum >= MIN_ARRAY ){
		stStatementAccess.break_statement.set( astBreakStmt, astFatherStmt );
	}else{
		CcThrowWarning( CC_STMT_BREAK_OUTLOOP_OR_SWITCH,
				stLexTokenAccess.codeScp.get( astCurrToken ),
				NULL, NULL );
	}
	astCurrToken = CcLexGetNextToken();
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
	if( currTokenKind != xLEX_SEMICOLON ){
		CcThrowWarning( CC_STMT_SYNTAX_ERROR,
				stLexTokenAccess.codeScp.get( astCurrToken ),
				stLexTokenAccess.name.get( astCurrToken ), NULL );
	}else{
		CcLexGetNextToken();
	}
	secondScp = stLexTokenAccess.codeScp.get( CcLexGetLF(1) );
	secondScp = stCoreCodeScpAccess.mergeCodeScp( firstScp, secondScp );
	stStatementAccess.codeScp.set( astBreakStmt, secondScp );
	CATCH(astBreakStmt);
	return( astBreakStmt ) ;
}
static AST ccStmtDefault( AST astParent ){
	AST	astCtlIndex ;
	U4	ulCtlKind ;
	AST	astSwitchIndex ;
	AST astChild;
	AST astDefaultStmt=0;
	AST   astCurrToken;
	U4    currTokenKind;
	AST  firstScp, secondScp;

	TRY;
	astCurrToken = CcLexGetCurrToken();
	firstScp = stLexTokenAccess.codeScp.get( astCurrToken );

	stStatementAccess.alloc(1);
	astDefaultStmt = stStatementAccess.getMax();
	stStatementAccess.parentKind.set( astDefaultStmt, KIND_STATEMENTINFO );
	stStatementAccess.parent_statement.set( astDefaultStmt, astParent );
	stStatementAccess.statmentKind.set( astDefaultStmt, xSTMT_DEFAULT );

	astCtlIndex = stCCLoopSwitchStackAccess.getMax();
    while( astCtlIndex >= MIN_ARRAY ){
    	astSwitchIndex = stCCLoopSwitchStackAccess.statement.get( astCtlIndex );
    	ulCtlKind = stStatementAccess.statmentKind.get( astSwitchIndex );
        if( ulCtlKind == xSTMT_SWITCH ){
            break ;
        }
        astCtlIndex-- ;
    }
    if( astCtlIndex < MIN_ARRAY ){
		CcThrowWarning( CC_STMT_DEFAULT_OUTSWITCH,
				stLexTokenAccess.codeScp.get( astCurrToken ),
				NULL, NULL );
    	astCurrToken = CcLexGetNextToken();
    	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
        while( currTokenKind != xLEX_SEMICOLON
        		&& currTokenKind != xLEX_COLON
        		&& currTokenKind != xLEX_CLOSEBLOCK
        		&& currTokenKind != xLEX_ENDOFFILE ){
        	astCurrToken = CcLexGetNextToken();
        	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
        }
        if( currTokenKind == xLEX_SEMICOLON
        		|| currTokenKind == xLEX_COLON ) {
        	CcLexGetNextToken();
        }
		secondScp = stLexTokenAccess.codeScp.get( CcLexGetLF(1) );
		secondScp = stCoreCodeScpAccess.mergeCodeScp( firstScp, secondScp );
		stStatementAccess.codeScp.set( astDefaultStmt, secondScp );
		return( astDefaultStmt ) ;
    }

	if (stStatementAccess.switch_default.get(astSwitchIndex) != 0){
		CcThrowWarning( CC_STMT_DEFAULT_OVERLAP,
				firstScp,
				NULL, NULL );
		CcThrowWarning( CC_STMT_DEFAULT_OVERLAP1ST,
				stStatementAccess.codeScp.get(
						stStatementAccess.switch_default.get(astSwitchIndex)),
				NULL, NULL );
	}else{
		 stStatementAccess.switch_default.set( astSwitchIndex, astDefaultStmt );
	}
	astCurrToken = CcLexGetNextToken();
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
	if( currTokenKind != xLEX_COLON ){
		CcThrowWarning( CC_STMT_SYNTAX_ERROR,
				stLexTokenAccess.codeScp.get( astCurrToken ),
				stLexTokenAccess.name.get( astCurrToken ), NULL );
	}else{
		CcLexGetNextToken();
	}
	/* get the body */
	astChild = ccStmtAnalyze( astDefaultStmt );
	if( astChild == 0 ){
		CcThrowWarning( CC_STMT_NEED_BODY,
				stLexTokenAccess.codeScp.get( astCurrToken ),
				"default", NULL );
	}
	stStatementAccess.default_statement.set( astDefaultStmt, astChild );
	secondScp = stLexTokenAccess.codeScp.get( CcLexGetLF(1) );
	secondScp = stCoreCodeScpAccess.mergeCodeScp( firstScp, secondScp );
	stStatementAccess.codeScp.set( astDefaultStmt, secondScp );
	CATCH(astDefaultStmt);
	return( astDefaultStmt ) ;
}
static AST ccStmtCase( AST astParent ){
	AST astCtrlStmtNum ;
	U4 lCtrlKind ;
	AST astExprInfo ;
	U4 ulEndToken[2] ;		 /* 式解析の終端			*/
	AST astConstIndex ;
	AST astConstType ;
	AST astSwitchIndex =0 ;
	AST astTempCaseStmt ;
	AST astAddedCase ;
	AST astCaseStmt=0;
	AST astChild;
	AST astTempExprValue ;
	AST astTempConstValue ;
	S4  result=0;
	AST   astCurrToken;
	U4    currTokenKind;
	AST  firstScp, secondScp;
	TRY;
	astCurrToken = CcLexGetCurrToken();
	firstScp = stLexTokenAccess.codeScp.get( astCurrToken );

	stStatementAccess.alloc(1);
	astCaseStmt = stStatementAccess.getMax();
	stStatementAccess.parentKind.set( astCaseStmt, KIND_STATEMENTINFO );
	stStatementAccess.parent_statement.set( astCaseStmt, astParent );
	stStatementAccess.statmentKind.set( astCaseStmt, xSTMT_CASE );

	astCtrlStmtNum = stCCLoopSwitchStackAccess.getMax();
    while( astCtrlStmtNum >= MIN_ARRAY ){
    	astSwitchIndex = stCCLoopSwitchStackAccess.statement.get( astCtrlStmtNum );
        lCtrlKind = stStatementAccess.statmentKind.get( astSwitchIndex );
        if( lCtrlKind == xSTMT_SWITCH ){
            break ;
        }
        astCtrlStmtNum-- ;
    }
    if( astCtrlStmtNum < MIN_ARRAY ){
		CcThrowWarning( CC_STMT_CASE_OUTSWITCH,
				stLexTokenAccess.codeScp.get( astCurrToken ),
				NULL, NULL );
    	astCurrToken = CcLexGetNextToken();
    	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
        while( currTokenKind != xLEX_SEMICOLON
        		&& currTokenKind != xLEX_COLON
        		&& currTokenKind != xLEX_CLOSEBLOCK
        		&& currTokenKind != xLEX_ENDOFFILE ){
        	astCurrToken = CcLexGetNextToken();
        	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
        }
        if( currTokenKind == xLEX_SEMICOLON
        		|| currTokenKind == xLEX_COLON ) {
        	CcLexGetNextToken();
        }
		secondScp = stLexTokenAccess.codeScp.get( CcLexGetLF(1) );
		secondScp = stCoreCodeScpAccess.mergeCodeScp( firstScp, secondScp );
		stStatementAccess.codeScp.set( astCaseStmt, secondScp );
		return( astCaseStmt ) ;
    }
    stStatementAccess.case_switch.set( astCaseStmt, astSwitchIndex );
	astCurrToken = CcLexGetNextToken();
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );

	ulEndToken[0] = xLEX_COLON ;
	ulEndToken[1] = xLEX_UNDEFINED ;

	astExprInfo = CcConstantExpression( ulEndToken, KIND_STATEMENTINFO, astCaseStmt  );
	astCurrToken = CcLexGetCurrToken();
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
	if( currTokenKind != xLEX_COLON ){
		CcThrowWarning( CC_STMT_SYNTAX_ERROR,
				stLexTokenAccess.codeScp.get( astCurrToken ),
				stLexTokenAccess.name.get( astCurrToken ), NULL );
	}else{
		astCurrToken = CcLexGetNextToken();
		currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
	}
	if( astExprInfo == 0 ){
		CcThrowWarning( CC_STMT_CASE_NEED_VALUE,
				stLexTokenAccess.codeScp.get( astCurrToken ),
				NULL, NULL );
	}else{
		stStatementAccess.case_constExp.set( astCaseStmt, astExprInfo );
	    if(! CcExpIsConstantValue(astExprInfo)){
			CcThrowWarning( CC_STMT_CASE_NEED_CONSTANT,
					stExpressionAccess.codeScp.get( astExprInfo ),
					NULL, NULL );
	    }else{
			astConstIndex = stExpressionAccess.constValue.get( astExprInfo ) ;
			astConstType = stExpressionAccess.type.get( astExprInfo );
			if( !CcTypeIsInteger(astConstType) ){
				CcThrowWarning( CC_STMT_CASE_NEED_INTEGER,
						stExpressionAccess.codeScp.get( astExprInfo ),
						NULL, NULL );
			}
			astAddedCase = stStatementAccess.switch_firstCase.get( astSwitchIndex );
			astTempCaseStmt = 0 ;
			result = -1;
			while( astAddedCase != 0 ){
				 astTempExprValue  = stStatementAccess.case_constExp.get( astAddedCase ) ;
				 astTempConstValue = stExpressionAccess.constValue.get( astTempExprValue ) ;

				 result = CcValueCompareIdx(astConstIndex, astTempConstValue) ;
#if 0 // 2012/07/13 because of trace_cmd  pathInfo
//				 if( result > 0 ){
//					 astTempCaseStmt = astAddedCase ;
//					 astAddedCase = stStatementAccess.case_nextCase.get( astAddedCase );
//				 }else if( result < 0 ){
//					 break ;
//				 }else {
//					 VARVALUE v = CcValueGetInteger( astConstIndex );
//					 if( v.sign < 0 ){
//						 sprintf(gblTempBuffer, "-%llu", v.u8Remainder );
//					 }else{
//						 sprintf(gblTempBuffer, "%llu", v.u8Remainder );
//					 }
//					 CcThrowWarning( CC_STMT_CASE_OVERLAP,
//								stExpressionAccess.codeScp.get( astExprInfo ),
//								gblTempBuffer, NULL );
//					 CcThrowWarning( CC_STMT_CASE_OVERLAP1ST,
//							 stStatementAccess.codeScp.get( astAddedCase ),
//								gblTempBuffer, NULL );
//					 break;
//				 }
#else
				 if( result == 0 ){
					 VARVALUE v = CcValueGetInteger( astConstIndex );
					 if( v.sign < 0 ){
						 sprintf(gblTempBuffer, "-%llu", v.u8Remainder );
					 }else{
						 sprintf(gblTempBuffer, "%llu", v.u8Remainder );
					 }
					 CcThrowWarning( CC_STMT_CASE_OVERLAP,
								stExpressionAccess.codeScp.get( astExprInfo ),
								gblTempBuffer, NULL );
					 CcThrowWarning( CC_STMT_CASE_OVERLAP1ST,
							 stStatementAccess.codeScp.get( astAddedCase ),
								gblTempBuffer, NULL );
					 break;
				 }else{
					 astTempCaseStmt = astAddedCase ;
					 astAddedCase = stStatementAccess.case_nextCase.get( astAddedCase );
				 }
#endif
			}
			if( result != 0 ){
				if( astTempCaseStmt == 0 ){
					stStatementAccess.switch_firstCase.set(astSwitchIndex, astCaseStmt);
				}else{
					stStatementAccess.case_nextCase.set(astTempCaseStmt, astCaseStmt);
				}
				// 2012/07/13 because of trace_cmd  pathInfo
//				if(astAddedCase != 0){
//					stStatementAccess.case_nextCase.set( astCaseStmt, astAddedCase );
//				}
			}
	    }
	}
	/* get the body */
	astChild = ccStmtAnalyze( astCaseStmt );
	if( astChild == 0 ){
		CcThrowWarning( CC_STMT_NEED_BODY,
				stLexTokenAccess.codeScp.get( astCurrToken ),
				"case", NULL );
	}
	stStatementAccess.case_statement.set( astCaseStmt, astChild );

	secondScp = stLexTokenAccess.codeScp.get( CcLexGetLF(1) );
	secondScp = stCoreCodeScpAccess.mergeCodeScp( firstScp, secondScp );
	stStatementAccess.codeScp.set( astCaseStmt, secondScp );
	CATCH(astCaseStmt);
    return( astCaseStmt ) ;
}
static AST ccStmtSwitch( AST astParent ){
	U4 ulEndToken[3] ;		 /* 式解析の終端			*/
	AST astExprInfo ;       /* 計算式情報			*/
	AST astSwitchStmt=0 ; /* SWITCH斁E��体情報            */
	AST astChild;
	AST   astCurrToken;
	U4    currTokenKind;
	AST  firstScp, secondScp;
	TRY;
	stStatementAccess.alloc(1);
	astSwitchStmt = stStatementAccess.getMax();
	stStatementAccess.parentKind.set( astSwitchStmt, KIND_STATEMENTINFO );
	stStatementAccess.parent_statement.set( astSwitchStmt, astParent );
	stStatementAccess.statmentKind.set( astSwitchStmt, xSTMT_SWITCH );

	astCurrToken = CcLexGetCurrToken();
	firstScp = stLexTokenAccess.codeScp.get( astCurrToken );

	astCurrToken = CcLexGetNextToken();
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
	if( currTokenKind == xLEX_OPENPAREN ){
		/* condition expression */
	    CcLexGetNextToken();
		ulEndToken[0] = xLEX_CLOSEPAREN;
		ulEndToken[1] = xLEX_UNDEFINED;
		astExprInfo = CcExpression( ulEndToken, KIND_STATEMENTINFO, astSwitchStmt  );

		astCurrToken = CcLexGetCurrToken();
		currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
		if( astExprInfo == 0 ){
			CcThrowWarning( CC_STMT_SYNTAX_ERROR,
					stLexTokenAccess.codeScp.get( astCurrToken ),
					stLexTokenAccess.name.get( astCurrToken ), NULL );
		}
		if( currTokenKind != xLEX_CLOSEPAREN ){
			CcThrowWarning( CC_STMT_SYNTAX_ERROR,
					stLexTokenAccess.codeScp.get( astCurrToken ),
					stLexTokenAccess.name.get( astCurrToken ), NULL );
		}else{
			astCurrToken = CcLexGetNextToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
		}

	}else{
		CcThrowWarning( CC_STMT_SYNTAX_ERROR,
				stLexTokenAccess.codeScp.get( astCurrToken ),
				stLexTokenAccess.name.get( astCurrToken ), NULL );
		while(TRUE)	{
		    if(    currTokenKind == xLEX_SEMICOLON
		        || currTokenKind == xLEX_OPENBLOCK
		        || currTokenKind == xLEX_ENDOFFILE
		        || currTokenKind == xLEX_CLOSEPAREN ){
		        break ;
		    }
		    astCurrToken = CcLexGetNextToken();
		    currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
		}

		if( currTokenKind == xLEX_CLOSEPAREN ){
		    astCurrToken = CcLexGetNextToken();
		    currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
		}else if( currTokenKind == xLEX_SEMICOLON ){
			secondScp = stLexTokenAccess.codeScp.get( astCurrToken );
			secondScp = stCoreCodeScpAccess.mergeCodeScp( firstScp, secondScp );
			stStatementAccess.codeScp.set( astSwitchStmt, secondScp );

			CcLexGetNextToken();
		    return astSwitchStmt ;
		}else if( currTokenKind == xLEX_ENDOFFILE ){
			secondScp = stLexTokenAccess.codeScp.get( CcLexGetLastOne() );
			secondScp = stCoreCodeScpAccess.mergeCodeScp( firstScp, secondScp );
			stStatementAccess.codeScp.set( astSwitchStmt, secondScp );

			return astSwitchStmt ;
		}
		astExprInfo = 0;
	}

	ccStmtPushLoopOrSwitch( astSwitchStmt );

	if( astExprInfo ){
		stStatementAccess.switch_condExp.set( astSwitchStmt, astExprInfo );
		ccStmtCheckExpType( xSTMT_SWITCH, astExprInfo) ;
	}
	/* get the body */
	astChild = ccStmtAnalyze( astSwitchStmt );
	if( astChild == 0 ){
		CcThrowWarning( CC_STMT_NEED_BODY,
				stLexTokenAccess.codeScp.get( astCurrToken ),
				"switch", NULL );
	}
	stStatementAccess.switch_body.set( astSwitchStmt, astChild );

	ccStmtPullLoopOrSwitch( );

	secondScp = stLexTokenAccess.codeScp.get( CcLexGetLF(1) );
	secondScp = stCoreCodeScpAccess.mergeCodeScp( firstScp, secondScp );
	stStatementAccess.codeScp.set( astSwitchStmt, secondScp );

    CATCH( astSwitchStmt );
	return( astSwitchStmt ) ;
}
static AST ccStmtDo( AST astParent ){
	AST  astExprInfo ;     /* 演算式情報    */
	U4  ulEndToken[3] ;
	AST   astChild;
	AST   astCurrToken;
	U4    currTokenKind;
	AST  firstScp, secondScp;
	AST astDoStmtInfo=0 ; /* Do文本体情報 */

	TRY;
	stStatementAccess.alloc(1);
	astDoStmtInfo = stStatementAccess.getMax();
	stStatementAccess.parentKind.set( astDoStmtInfo, KIND_STATEMENTINFO );
	stStatementAccess.parent_statement.set( astDoStmtInfo, astParent );
	stStatementAccess.statmentKind.set( astDoStmtInfo, xSTMT_DO );


	astCurrToken = CcLexGetCurrToken();
	firstScp = stLexTokenAccess.codeScp.get( astCurrToken );

	ccStmtPushLoopOrSwitch( astDoStmtInfo );

	astCurrToken = CcLexGetNextToken();

	/* get the body */
	astChild = ccStmtAnalyze( astDoStmtInfo );
	if( astChild == 0 ){
		CcThrowWarning( CC_STMT_NEED_BODY,
				stLexTokenAccess.codeScp.get( astCurrToken ),
				"do", NULL );
	}
	stStatementAccess.do_body.set( astDoStmtInfo, astChild );

	ccStmtPullLoopOrSwitch();

	astCurrToken = CcLexGetCurrToken();
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );

	if( currTokenKind == xLEX_WHILE ){

		astCurrToken = CcLexGetNextToken();
		currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );

		if( currTokenKind != xLEX_OPENPAREN ){
			CcThrowWarning( CC_STMT_SYNTAX_ERROR,
					stLexTokenAccess.codeScp.get( astCurrToken ),
					stLexTokenAccess.name.get( astCurrToken ), NULL );
			while(TRUE)	{
			    if(    currTokenKind == xLEX_SEMICOLON
			        || currTokenKind == xLEX_OPENBLOCK
			        || currTokenKind == xLEX_ENDOFFILE ){
			        break ;
			    }
				astCurrToken = CcLexGetNextToken();
				currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			}
			if( currTokenKind == xLEX_SEMICOLON ){
				astCurrToken = CcLexGetNextToken();
			}
			astExprInfo = 0;
		}else{
			astCurrToken = CcLexGetNextToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			/* 条件式を解析して、ﾊﾟﾗﾒｰﾀに設定する				*/
			ulEndToken[0] = xLEX_CLOSEPAREN ;
			ulEndToken[1] = xLEX_SEMICOLON ;
			ulEndToken[2] = xLEX_UNDEFINED ;

			astExprInfo = CcExpression( ulEndToken, KIND_STATEMENTINFO, astDoStmtInfo  );
			astCurrToken = CcLexGetCurrToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			if( astExprInfo == 0 ){
				CcThrowWarning( CC_STMT_SYNTAX_ERROR,
						stLexTokenAccess.codeScp.get( astCurrToken ),
						stLexTokenAccess.name.get( astCurrToken ), NULL );
			}else{
				stStatementAccess.do_condExp.set( astDoStmtInfo, astExprInfo );
				ccStmtCheckExpType( xSTMT_DO, astExprInfo) ;
			}
		    if( currTokenKind == xLEX_CLOSEPAREN ){
				astCurrToken = CcLexGetNextToken();
				currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
			}else{
				CcThrowWarning( CC_STMT_SYNTAX_ERROR,
						stLexTokenAccess.codeScp.get( astCurrToken ),
						stLexTokenAccess.name.get( astCurrToken ), NULL );
			}
		    if( currTokenKind != xLEX_SEMICOLON ){
				CcThrowWarning( CC_STMT_SYNTAX_ERROR,
						stLexTokenAccess.codeScp.get( astCurrToken ),
						stLexTokenAccess.name.get( astCurrToken ), NULL );
			}else{
				astCurrToken = CcLexGetNextToken();
			}
		}


	}else{
		CcThrowWarning( CC_STMT_SYNTAX_ERROR,
				stLexTokenAccess.codeScp.get( astCurrToken ),
				stLexTokenAccess.name.get( astCurrToken ), NULL );
	}
	secondScp = stLexTokenAccess.codeScp.get( CcLexGetLF(1) );
	secondScp = stCoreCodeScpAccess.mergeCodeScp( firstScp, secondScp );
	stStatementAccess.codeScp.set( astDoStmtInfo, secondScp );
	CATCH(astDoStmtInfo);
	return( astDoStmtInfo ) ;
}
static AST ccStmtWhile( AST astParent ){
	AST  astExprInfo ;     /* 演算式情報    */
	AST  astWhileStmt=0 ;  /* For本体情報 */
	U4  ulEndToken[3] ;
	AST   astChild;
	AST   astCurrToken;
	U4    currTokenKind;
	AST  firstScp, secondScp;

	TRY;
	stStatementAccess.alloc(1);
	astWhileStmt = stStatementAccess.getMax();
	stStatementAccess.parentKind.set( astWhileStmt, KIND_STATEMENTINFO );
	stStatementAccess.parent_statement.set( astWhileStmt, astParent );
	stStatementAccess.statmentKind.set( astWhileStmt, xSTMT_WHILE );

	astCurrToken = CcLexGetCurrToken();
	firstScp = stLexTokenAccess.codeScp.get( astCurrToken );

	ccStmtPushLoopOrSwitch( astWhileStmt );

	astCurrToken = CcLexGetNextToken();
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
	if( currTokenKind == xLEX_OPENPAREN ){
		/* condition expression */
	    CcLexGetNextToken();
		ulEndToken[0] = xLEX_CLOSEPAREN;
		ulEndToken[1] = xLEX_UNDEFINED;
		astExprInfo = CcExpression( ulEndToken, KIND_STATEMENTINFO, astWhileStmt  );

		astCurrToken = CcLexGetCurrToken();
		currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
		if( astExprInfo == 0 ){
			CcThrowWarning( CC_STMT_SYNTAX_ERROR,
					stLexTokenAccess.codeScp.get( astCurrToken ),
					stLexTokenAccess.name.get( astCurrToken ), NULL );
		}else{
			stStatementAccess.while_condExp.set( astWhileStmt, astExprInfo );
			ccStmtCheckExpType( xSTMT_WHILE, astExprInfo) ;
		}
		if( currTokenKind != xLEX_CLOSEPAREN ){
			CcThrowWarning( CC_STMT_SYNTAX_ERROR,
					stLexTokenAccess.codeScp.get( astCurrToken ),
					stLexTokenAccess.name.get( astCurrToken ), NULL );
		}else{
			astCurrToken = CcLexGetNextToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
		}
	}else{
		CcThrowWarning( CC_STMT_SYNTAX_ERROR,
				stLexTokenAccess.codeScp.get( astCurrToken ),
				stLexTokenAccess.name.get( astCurrToken ), NULL );
		while(TRUE)	{
		    if(    currTokenKind == xLEX_SEMICOLON
		        || currTokenKind == xLEX_OPENBLOCK
		        || currTokenKind == xLEX_ENDOFFILE
		        || currTokenKind == xLEX_CLOSEPAREN ){
		        break ;
		    }
		    astCurrToken = CcLexGetNextToken();
		    currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
		}

		if( currTokenKind == xLEX_CLOSEPAREN ){
		    astCurrToken = CcLexGetNextToken();
		    currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
		}else if( currTokenKind == xLEX_SEMICOLON ){
			secondScp = stLexTokenAccess.codeScp.get( astCurrToken );
			secondScp = stCoreCodeScpAccess.mergeCodeScp( firstScp, secondScp );
			stStatementAccess.codeScp.set( astWhileStmt, secondScp );

			CcLexGetNextToken();
		    return astWhileStmt ;
		}else if( currTokenKind == xLEX_ENDOFFILE ){
			secondScp = stLexTokenAccess.codeScp.get( CcLexGetLastOne() );
			secondScp = stCoreCodeScpAccess.mergeCodeScp( firstScp, secondScp );
			stStatementAccess.codeScp.set( astWhileStmt, secondScp );

			return astWhileStmt ;
		}
		astExprInfo = 0;
	}


	/* get the body */
	astChild = ccStmtAnalyze( astWhileStmt );
	if( astChild == 0 ){
		CcThrowWarning( CC_STMT_NEED_BODY,
				stLexTokenAccess.codeScp.get( astCurrToken ),
				"while", NULL );
	}
	stStatementAccess.while_body.set( astWhileStmt, astChild );

	ccStmtPullLoopOrSwitch();
	secondScp = stLexTokenAccess.codeScp.get( CcLexGetLF(1) );
	secondScp = stCoreCodeScpAccess.mergeCodeScp( firstScp, secondScp );
	stStatementAccess.codeScp.set( astWhileStmt, secondScp );
    CATCH(astWhileStmt);
	return( astWhileStmt ) ;
}
static AST ccStmtFor( AST astParent ){
	AST  astExprInfo ;     /* 演算式情報    */
	AST  astDecStmtInfo ;   /* 宣言情報       */
	AST  astForStmt =0;  /* For本体情報 */
	U4  ulEndToken[3] ;
	BOOL		bSkip = FALSE;
	AST   astChild;
	AST   astCurrToken;
	U4    currTokenKind;
	AST  firstScp, secondScp;

	TRY;
	stStatementAccess.alloc(1);
	astForStmt = stStatementAccess.getMax();
	stStatementAccess.parentKind.set( astForStmt, KIND_STATEMENTINFO );
	stStatementAccess.parent_statement.set( astForStmt, astParent );
	stStatementAccess.statmentKind.set( astForStmt, xSTMT_FOR );

	astCurrToken = CcLexGetCurrToken();
	firstScp = stLexTokenAccess.codeScp.get( astCurrToken );

	astCurrToken = CcLexGetNextToken();
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
	if( currTokenKind != xLEX_OPENPAREN ){
		CcThrowWarning( CC_STMT_SYNTAX_ERROR,
				stLexTokenAccess.codeScp.get( astCurrToken ),
				stLexTokenAccess.name.get( astCurrToken ), NULL );
		while(TRUE){
		    if(    currTokenKind == xLEX_SEMICOLON
		        || currTokenKind == xLEX_OPENBLOCK
		        || currTokenKind == xLEX_ENDOFFILE
		        || currTokenKind == xLEX_CLOSEPAREN )  {
		        break ;
		    }
			astCurrToken = CcLexGetNextToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
		}

		if(    currTokenKind == xLEX_SEMICOLON
		    || currTokenKind == xLEX_CLOSEPAREN ){
			astCurrToken = CcLexGetNextToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
		}
		secondScp = stLexTokenAccess.codeScp.get( astCurrToken );
		secondScp = stCoreCodeScpAccess.mergeCodeScp( firstScp, secondScp );
		stStatementAccess.codeScp.set( astForStmt, secondScp );
		return( astForStmt ) ;
	}
	astCurrToken = CcLexGetNextToken();
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );

	ccStmtPushLoopOrSwitch( astForStmt );

	/* 初期化文 */
	if (CcDeclChkType(astCurrToken) == TRUE) {

		astDecStmtInfo = CcDeclaration(xNAMESPACE_ORD);
		CcThrowWarning( CC_STMT_FOR_INITEXP_DECL,
				stDeclarationAccess.codeScp.get( astDecStmtInfo ),
				NULL, NULL );
		stStatementAccess.for_Init_Decl.set(astForStmt, astDecStmtInfo);
		stDeclarationAccess.parentKind.set(astDecStmtInfo,
				KIND_STATEMENTINFO);
		stDeclarationAccess.parentIdx.set(astDecStmtInfo, astForStmt);
	} else {
		ulEndToken[0] = xLEX_SEMICOLON;
		ulEndToken[1] = xLEX_CLOSEPAREN;
		ulEndToken[2] = xLEX_UNDEFINED;

		astExprInfo = CcExpression(ulEndToken, KIND_STATEMENTINFO,
				astForStmt);

		astCurrToken = CcLexGetCurrToken();
		currTokenKind = stLexTokenAccess.tokenKind.get(astCurrToken);
		if (currTokenKind == xLEX_SEMICOLON) {
			astCurrToken = CcLexGetNextToken();
			currTokenKind = stLexTokenAccess.tokenKind.get(astCurrToken);
		} else if (currTokenKind == xLEX_CLOSEPAREN) {
			CcThrowWarning( CC_STMT_SYNTAX_ERROR,
					stLexTokenAccess.codeScp.get( astCurrToken ),
					stLexTokenAccess.name.get( astCurrToken ), NULL );
			astCurrToken = CcLexGetNextToken();
			currTokenKind = stLexTokenAccess.tokenKind.get(astCurrToken);
			bSkip = TRUE;
		} else {
			CcThrowWarning( CC_STMT_SYNTAX_ERROR,
					stLexTokenAccess.codeScp.get( astCurrToken ),
					stLexTokenAccess.name.get( astCurrToken ), NULL );
			bSkip = TRUE;
		}

		if (astExprInfo >= MIN_ARRAY) {
			stStatementAccess.for_initExp.set(astForStmt, astExprInfo);
		}
	}
	if (bSkip == FALSE) {
		/* 判定式 */
		ulEndToken[0] = xLEX_SEMICOLON;
		ulEndToken[1] = xLEX_CLOSEPAREN;
		ulEndToken[2] = xLEX_UNDEFINED;

		astExprInfo = CcExpression(ulEndToken, KIND_STATEMENTINFO,
				astForStmt);
		astCurrToken = CcLexGetCurrToken();
		currTokenKind = stLexTokenAccess.tokenKind.get(astCurrToken);
		if (currTokenKind == xLEX_SEMICOLON) {
			astCurrToken = CcLexGetNextToken();
			currTokenKind = stLexTokenAccess.tokenKind.get(astCurrToken);
		} else if (currTokenKind == xLEX_CLOSEPAREN) {
			CcThrowWarning( CC_STMT_SYNTAX_ERROR,
					stLexTokenAccess.codeScp.get( astCurrToken ),
					stLexTokenAccess.name.get( astCurrToken ), NULL );
			astCurrToken = CcLexGetNextToken();
			currTokenKind = stLexTokenAccess.tokenKind.get(astCurrToken);
			bSkip = TRUE;
		} else {
			CcThrowWarning( CC_STMT_SYNTAX_ERROR,
					stLexTokenAccess.codeScp.get( astCurrToken ),
					stLexTokenAccess.name.get( astCurrToken ), NULL );
			bSkip = TRUE;
		}
		if (astExprInfo >= MIN_ARRAY) {
			stStatementAccess.for_CondExp.set(astForStmt, astExprInfo);
			ccStmtCheckExpType(xSTMT_FOR, astExprInfo);
		}
	}
	if (bSkip == FALSE) {
		/* INC・DEC */
		ulEndToken[0] = xLEX_CLOSEPAREN;
		ulEndToken[1] = xLEX_OPENBLOCK;
		ulEndToken[2] = xLEX_UNDEFINED;

		astExprInfo = CcExpression(ulEndToken, KIND_STATEMENTINFO,
				astForStmt);
		astCurrToken = CcLexGetCurrToken();
		currTokenKind = stLexTokenAccess.tokenKind.get(astCurrToken);
		if (currTokenKind == xLEX_CLOSEPAREN) {
			astCurrToken = CcLexGetNextToken();
			currTokenKind = stLexTokenAccess.tokenKind.get(astCurrToken);
		} else {
			CcThrowWarning( CC_STMT_SYNTAX_ERROR,
					stLexTokenAccess.codeScp.get( astCurrToken ),
					stLexTokenAccess.name.get( astCurrToken ), NULL );
			bSkip = TRUE;
		}
		if (astExprInfo >= MIN_ARRAY) {
			stStatementAccess.for_IncExp.set(astForStmt, astExprInfo);
		}
	}
	/* get the body */
	astChild = ccStmtAnalyze( astForStmt );
	if( astChild == 0 ){
		CcThrowWarning( CC_STMT_NEED_BODY,
				stLexTokenAccess.codeScp.get( astCurrToken ),
				"for", NULL );
	}
	stStatementAccess.for_Body.set( astForStmt, astChild );

	ccStmtPullLoopOrSwitch();
	secondScp = stLexTokenAccess.codeScp.get( CcLexGetLF(1) );
	secondScp = stCoreCodeScpAccess.mergeCodeScp( firstScp, secondScp );
	stStatementAccess.codeScp.set( astForStmt, secondScp );
    CATCH(astForStmt);
	return( astForStmt ) ;
}
static AST  ccStmtIf( astParent ) {
	U4   ulEndToken[2];	/* 式解析の終端			*/
	AST	astExprInfo ;    /* 式構造の添字			*/
	AST   astIfStmtInfo=0 ;  /* IF本体文の情報                   */
	AST   astChild;
	AST   astCurrToken;
	U4    currTokenKind;
	AST  firstScp, secondScp;

	TRY;
	/* new if-statement */
	stStatementAccess.alloc(1);
	astIfStmtInfo = stStatementAccess.getMax();
	stStatementAccess.parentKind.set( astIfStmtInfo, KIND_STATEMENTINFO );
	stStatementAccess.parent_statement.set( astIfStmtInfo, astParent );
	stStatementAccess.statmentKind.set( astIfStmtInfo, xSTMT_IF );

	/* starting-location */
	astCurrToken = CcLexGetCurrToken();
	firstScp = stLexTokenAccess.codeScp.get( astCurrToken );

	astCurrToken = CcLexGetNextToken();
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
	if( currTokenKind == xLEX_OPENPAREN ){
		/* condition expression */
	    CcLexGetNextToken();
		ulEndToken[0] = xLEX_CLOSEPAREN;
		ulEndToken[1] = xLEX_UNDEFINED;
		astExprInfo = CcExpression( ulEndToken, KIND_STATEMENTINFO, astIfStmtInfo  );

		astCurrToken = CcLexGetCurrToken();
		currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
		if( astExprInfo == 0 ){
			CcThrowWarning( CC_STMT_SYNTAX_ERROR,
					stLexTokenAccess.codeScp.get( astCurrToken ),
					stLexTokenAccess.name.get( astCurrToken ), NULL );
		}else{
			stStatementAccess.if_condExp.set( astIfStmtInfo, astExprInfo );
			ccStmtCheckExpType( xSTMT_IF, astExprInfo) ;
		}
		if( currTokenKind != xLEX_CLOSEPAREN ){
			CcThrowWarning( CC_STMT_SYNTAX_ERROR,
					stLexTokenAccess.codeScp.get( astCurrToken ),
					stLexTokenAccess.name.get( astCurrToken ), NULL );
		}else{
			astCurrToken = CcLexGetNextToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
		}
	}else{
		CcThrowWarning( CC_STMT_SYNTAX_ERROR,
				stLexTokenAccess.codeScp.get( astCurrToken ),
				stLexTokenAccess.name.get( astCurrToken ), NULL );
		while(TRUE)	{
		    if(    currTokenKind == xLEX_SEMICOLON
		        || currTokenKind == xLEX_OPENBLOCK
		        || currTokenKind == xLEX_ENDOFFILE
		        || currTokenKind == xLEX_CLOSEPAREN ){
		        break ;
		    }
		    astCurrToken = CcLexGetNextToken();
		    currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
		}
		if( currTokenKind == xLEX_CLOSEPAREN ){
		    astCurrToken = CcLexGetNextToken();
		    currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
		}else if( currTokenKind == xLEX_SEMICOLON ){
			secondScp = stLexTokenAccess.codeScp.get( astCurrToken );
			secondScp = stCoreCodeScpAccess.mergeCodeScp( firstScp, secondScp );
			stStatementAccess.codeScp.set( astIfStmtInfo, secondScp );

			CcLexGetNextToken();

		    return astIfStmtInfo ;
		}else if( currTokenKind == xLEX_ENDOFFILE ){
			secondScp = stLexTokenAccess.codeScp.get( CcLexGetLastOne() );
			secondScp = stCoreCodeScpAccess.mergeCodeScp( firstScp, secondScp );
			stStatementAccess.codeScp.set( astIfStmtInfo, secondScp );

			return astIfStmtInfo ;
		}
		astExprInfo = 0;
	}


	/* get the body */
	astChild = ccStmtAnalyze( astIfStmtInfo );
	if( astChild == 0 ){
		CcThrowWarning( CC_STMT_NEED_BODY,
				stLexTokenAccess.codeScp.get( astCurrToken ),
				"if", NULL );
	}else{
		stStatementAccess.if_body.set( astIfStmtInfo, astChild );
	}


	/* whether there is a else-statement */
	astCurrToken = CcLexGetCurrToken();
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
	if( currTokenKind == xLEX_ELSE ){
		/* get the else body */
		CcLexGetNextToken();
		astChild = ccStmtAnalyze( astIfStmtInfo );
		if( astChild == 0 ){
			CcThrowWarning( CC_STMT_NEED_BODY,
					stLexTokenAccess.codeScp.get( astCurrToken ),
					"else", NULL );
		}
		stStatementAccess.if_else_body.set( astIfStmtInfo, astChild );
	}
	/* ending location */
	secondScp = stLexTokenAccess.codeScp.get( CcLexGetLF(1) );
	secondScp = stCoreCodeScpAccess.mergeCodeScp( firstScp, secondScp );
	stStatementAccess.codeScp.set( astIfStmtInfo, secondScp );
	CATCH(astIfStmtInfo);
	return( astIfStmtInfo ) ;
}
static AST  ccStmtAnalyze( AST astParent ){
	AST astCurrToken;
	U4  currTokenKind;

	astCurrToken = CcLexGetCurrToken();
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
	if( currTokenKind == xLEX_OPENBLOCK ){
		return ccStmtBlock( KIND_STATEMENTINFO, astParent );
	}else if( currTokenKind == xLEX_IF ){
		return ccStmtIf( astParent );  /* 1 */
	}else if( currTokenKind == xLEX_FOR ){
		return ccStmtFor( astParent ); /* 2 */
	}else if( currTokenKind == xLEX_WHILE ){
		return ccStmtWhile( astParent ); /* 3 */
	}else if( currTokenKind == xLEX_DO ){
		return ccStmtDo( astParent ); /* 4 */
	}else if( currTokenKind == xLEX_SWITCH ){
		return ccStmtSwitch( astParent ); /* 5 */
	}else if( currTokenKind == xLEX_CASE ){
		return ccStmtCase( astParent ); /* 6 */
	}else if( currTokenKind == xLEX_DEFAULT ){
		return ccStmtDefault( astParent );/* 7 */
	}else if( currTokenKind == xLEX_BREAK ){
		return ccStmtBreak( astParent );/* 8 */
	}else if( currTokenKind == xLEX_CONTINUE ){
		return ccStmtContinue( astParent );/* 9 */
	}else if( currTokenKind == xLEX_RETURN ){
		return ccStmtReturn( astParent );/* 10 */
	}else if( currTokenKind == xLEX_GOTO ){
		return ccStmtGoto(  astParent );/* 11 */
	}else if( ccStmtIsLabelStmt( ) ){
		return ccStmtLabel(  astParent );/* 12 */
	}else if( currTokenKind & xLEXBIT_CTRL ){
		CcThrowWarning( CC_STMT_SYNTAX_ERROR,
				stLexTokenAccess.codeScp.get( astCurrToken ),
				stLexTokenAccess.name.get( astCurrToken ), NULL );
		// else
		CcLexGetNextToken();
		return 0;
	}else if( CcDeclIsDeclaration () ){
		return 0;
	}
	return ccStmtExpression( astParent );
}
static VOID ccStmtAddFuncPara2Block( AST astFuncSym, AST astBlock ){
	AST astParaChain;
	AST astFuncType;
	AST astTempValue;
	PSZ pszName;

	astFuncType = stSymbolInfoAccess.type.get( astFuncSym );
	astParaChain = stTypeInfoAccess.memChain.get( astFuncType );
	while (astParaChain != 0) {
		astTempValue = stUniteChainAccess.parameter_sym.get( astParaChain );
		if( astTempValue == 0 ){
			if( stUniteChainAccess.next.get( astParaChain ) == 0 ){
				break;
			}else{
				CcThrowWarning( CC_DECL_FUNC_PARAM_NONAME,
						stSymbolInfoAccess.codeScp.get( astFuncSym ),
						stSymbolInfoAccess.name.get( astFuncSym ), NULL );
				astParaChain = stUniteChainAccess.next.get( astParaChain );
				continue;
			}
		}
		pszName = stSymbolInfoAccess.name.get( astTempValue );
		if( str_length( pszName ) == 0 ){
			CcThrowWarning( CC_DECL_FUNC_PARAM_NONAME,
					stSymbolInfoAccess.codeScp.get( astFuncSym ),
					stSymbolInfoAccess.name.get( astFuncSym ), NULL );
			astParaChain = stUniteChainAccess.next.get( astParaChain );
			continue;
		}
		if( stSymbolInfoAccess.type.get( astTempValue ) == 0 ){
			CcThrowWarning( CC_DECL_FUNC_PARAM_NOTYPE,
					stSymbolInfoAccess.codeScp.get( astFuncSym ),
					pszName, NULL );
			stSymbolInfoAccess.type.set( astTempValue, TYPE_INT );
		}
		CcBlockAddExistSymbol( astBlock, astTempValue );
		astParaChain = stUniteChainAccess.next.get( astParaChain );
	}
}
static AST ccStmtBlock( U2 kind, AST parent ){
	BOOL bRet;
	AST astBlockStmt=0;
	AST astCurBlock;
	AST astPreStmt;
//	AST astPreDecl;
	AST astTempValue;
	AST astChild;
	AST astDecl;
	AST astCurrToken;
	U4  currTokenKind;
	AST firstScp, secondScp;

	TRY;
	astCurrToken = CcLexGetCurrToken();
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
	if( currTokenKind == xLEX_OPENBLOCK ){
		astCurrToken = CcLexGetNextToken();
		currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
		firstScp = stLexTokenAccess.codeScp.get( astCurrToken );
	}else{
		return 0;
	}
	CcBlockEntryBlock();
	stStatementAccess.alloc(1);
	astBlockStmt = stStatementAccess.getMax();
	stStatementAccess.statmentKind.set( astBlockStmt, xSTMT_BLOCK );

	astCurBlock = stBlockNestAccess.getMax();
	stStatementAccess.parentKind.set( astBlockStmt, kind );

    if (kind == KIND_SYMDEFINFO ) {
    	stStatementAccess.parent_Symbol.set( astBlockStmt, parent );
    	if(parent >= MIN_ARRAY){

    		ccStmtAddFuncPara2Block( parent, astCurBlock );
    	}
	} else if (kind == KIND_STATEMENTINFO) {
		stStatementAccess.parent_statement.set( astBlockStmt, parent );
	} else {
		stStatementAccess.parent_expression.set( astBlockStmt, parent );
	}
	astCurrToken = CcLexGetCurrToken();
	currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
	astPreStmt = 0;
//	astPreDecl = 0;
	while (1) {
		astTempValue = astCurrToken;
		if (currTokenKind == xLEX_ENDOFFILE) {
			CcThrowWarning( CC_STMT_SYNTAX_ERROR,
					stLexTokenAccess.codeScp.get( CcLexGetLF(1) ),
					stLexTokenAccess.name.get( CcLexGetLF(1) ), NULL );
			break;
		}
		if( currTokenKind == xLEX_CLOSEBLOCK) {
			CcLexGetNextToken();
			break;
		}
		astChild = 0;
		bRet = CcDeclIsDeclaration(  );
		if( bRet ){
			astDecl = CcDeclaration( xNAMESPACE_ORD );
			if( astDecl > 0 ){
				/* new if-statement */
				stStatementAccess.alloc(1);
				astChild = stStatementAccess.getMax();
				stStatementAccess.parentKind.set( astChild, KIND_STATEMENTINFO );
				stStatementAccess.parent_statement.set( astChild, astBlockStmt );
				stStatementAccess.statmentKind.set( astChild, xSTMT_DEC );
				stStatementAccess.dec_declaration.set( astChild, astDecl );
				secondScp = stDeclarationAccess.codeScp.get( astDecl );
				stStatementAccess.codeScp.set( astChild, secondScp );
			}
		}else{
			astChild = ccStmtAnalyze( astBlockStmt );
		}
		if( astChild > 0 ){
			if( astPreStmt == 0 ){
				stStatementAccess.block_stmtlist.set( astBlockStmt, astChild );
				astPreStmt = astChild;
			}else{
				stStatementAccess.next.set( astPreStmt, astChild );
				stStatementAccess.before.set( astChild, astPreStmt );
				astPreStmt = astChild;
			}
		}
		astCurrToken = CcLexGetCurrToken();
		currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
		if (astTempValue == astCurrToken) {
			astCurrToken = CcLexGetNextToken();
			currTokenKind = stLexTokenAccess.tokenKind.get( astCurrToken );
		}
	}
	CcBlockQuitBlock();

    secondScp = stLexTokenAccess.codeScp.get( CcLexGetLF(1) );
    secondScp = stCoreCodeScpAccess.mergeCodeScp( firstScp, secondScp );
    stStatementAccess.codeScp.set( astBlockStmt, secondScp );
	CATCH(astBlockStmt);
	return astBlockStmt;
}
VOID CcStmtInit(VOID){

}
AST CcStmtBlockInExp( U2 kind, AST parent ){
	return ccStmtBlock( kind, parent );
}
AST CcStmtFuncBody( U2 kind, AST parent ){
	AST  astFuncBody;
	AST  astFunc;
	astFunc = gblFunctionSym;
	gblFunctionSym = parent;
	astFuncBody = ccStmtBlock( kind, parent );
	gblFunctionSym = astFunc;
	return astFuncBody;
}
AST CcStmtGetLastType( AST astStmt ){
	U2 kind = stStatementAccess.statmentKind.get( astStmt );
	if( kind == STMT_EXP ){
		AST exp = stStatementAccess.exp_exp.get( astStmt );
		return stExpressionAccess.castedType.get( exp );
	}else if( kind == STMT_LABEL ){
		return CcStmtGetLastType(stStatementAccess.label_statement.get( astStmt ));
	}
	return TYPE_VOID;
}
AST  CcStmtGetCurrFunction( VOID ){
	return gblFunctionSym;
}
